// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <align.h>

#include "runtime_types.h"
#include "mem_alloc.h"

// Trampolines need to run in memory that is both writable and executable.
// We solve this problem simply by making the heap executable.
// This should go away once closures are changed for Go 1.1

// Allocate a trampoline of SIZE bytes that will use the closure in CLOSURE.
void *__go_allocate_trampoline(uintptr size, void *closure);

void *
__go_allocate_trampoline(uintptr size, void *closure)
{
	uintptr full_size;
	byte *ret;

	// Because the garbage collector only looks at aligned addresses, we
	// need to store the closure at an aligned address to ensure that it
	// sees it.
	full_size = ALIGN_UP(size, sizeof(void *)) + sizeof(void *);
	ret = runtime_mallocgc(full_size, 0, 1, 1);
	__builtin_memcpy(ret + full_size - sizeof(void *), &closure, sizeof(void *));

	return (void *)ret;
}
